#include"SceneSim.hpp"
#include"FuncApp.hpp"
#include"../Protocol/MapProtocol.hpp"
#include"../Protocol/Seralize.hpp"
#include"RpcClient.hpp"
#include<iostream>
#include<cmath>

namespace SC_SUN
{


    SceneSim::SceneSim(FuncApp& app)
        :mApp(app)
    {
        
    }

    SceneSim::~SceneSim()
    {

    }

    void SceneSim::SetDefaultScene()
    {
        //获取场景列表
        ScGetSceneListMSG sceneReq;
        sceneReq.scenes.push_back(SC_GET_SCENE_LIST_MSG);
        mApp.GetRpc()->SendMsg<ScGetSceneListMSG>(SC_GET_SCENE_LIST_MSG, sceneReq);
        mApp.GetRpc()->RecvMsg<ScGetSceneListMSG>(sceneReq);

        //设置场景
        ScSetSceneMSG sceneSet;
        sceneSet.msg = sceneReq.scenes[0];
        mApp.GetRpc()->SendMsg<ScSetSceneMSG>(SC_SET_SCENE_MSG, sceneSet);
        mApp.GetRpc()->RecvMsg<ScSetSceneMSG>(sceneSet);
        mCurScene = sceneReq.scenes[0];

        //获取场景仿真时间相关
        SceneTimeInfoMsg sceneTime = {};
        mApp.GetRpc()->SendMsg<SceneTimeInfoMsg>(SC_GET_SCENE_TIME_INFO_MSG, sceneTime);
        mApp.GetRpc()->RecvMsg<SceneTimeInfoMsg>(sceneTime);
        mSatStep = sceneTime.mSatStep;
        mGNSSStep = sceneTime.mGNSSStep;
        mGNSSTotal = sceneTime.mGNSSTotal;
        mSecStep = sceneTime.mSecStep;
        mSecTotal = sceneTime.mSecTotal;

        //计算仿真相关
        mTotalFrame = int(std::min(mGNSSTotal, mSecTotal) / std::min(mGNSSStep, mSecStep));
        mCurFrame = 0;
    }

    bool SceneSim::Start()
    {
        SetDefaultScene();

        mPlayThd = new std::thread([this]{

            //仿真线程没有退出就一直执行
            while(!mIsQuit)
            {
                //如果处于暂停状态,休眠节能和原地空转
                mIsPlay.wait(false);
                if (mIsPlay == false)
                {
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                    continue;
                }

                //处理正常业务


            }

        });
        return true;
    }

    void SceneSim::Stop()
    {
        mIsQuit = true;
        if (mPlayThd->joinable())
        {
            mPlayThd->join();
            mPlayThd = nullptr;
        }
    }

    void SceneSim::SetCurScene(const std::string& scene)
    {
        Pause();

        //设置场景
        ScSetSceneMSG sceneSet;
        sceneSet.msg = scene;
        mApp.GetRpc()->SendMsg<ScSetSceneMSG>(SC_SET_SCENE_MSG, sceneSet);
        mApp.GetRpc()->RecvMsg<ScSetSceneMSG>(sceneSet);
        mCurScene = scene;

        //获取场景仿真时间相关
        SceneTimeInfoMsg sceneTime = {};
        mApp.GetRpc()->SendMsg<SceneTimeInfoMsg>(SC_GET_SCENE_TIME_INFO_MSG, sceneTime);
        mApp.GetRpc()->RecvMsg<SceneTimeInfoMsg>(sceneTime);
        mSatStep = sceneTime.mSatStep;
        mGNSSStep = sceneTime.mGNSSStep;
        mGNSSTotal = sceneTime.mGNSSTotal;
        mSecStep = sceneTime.mSecStep;
        mSecTotal = sceneTime.mSecTotal;

        //计算仿真相关
        mTotalFrame = int(std::min(mGNSSTotal, mSecTotal) / std::min(mGNSSStep, mSecStep));
        mCurFrame = 0;

        ResetPlay();
    }

    void SceneSim::ResetPlay()
    {
        Pause();
        mCurFrame = 0;
    }

    bool SceneSim::NextFrame()
    {
        Pause();
        mCurFrame++;
        Play();
        return true;
    }

    bool SceneSim::PreFrame()
    {
        Pause();
        mCurFrame--;
        Play();
        return true;
    }

    bool SceneSim::Pause()
    {
        mIsPlay = false;
        return true;
    }

    bool SceneSim::Play()
    {
        mIsPlay = true;
        mIsPlay.notify_one();
        return true;
    }

}